package com.merry.boot.config;

import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

import com.merry.boot.bean.User;

import ch.qos.logback.core.db.DBHelper;

/**
 * 配置类
 * @Configuration：标识一个配置类
 *  在spring 5.2之后的版本中有一个属性：
 *      proxyBeanMethods：默认为true，表示为代理bean的方法。
 *      在springboot中@Bean注解生成的对象默认是单实例的，但是如果proxyBeanMethods为false，那么获取的对象就变成了多实例了。
 *          true：会给config类生成代理对象，当直接调用方法时，不会生成新的对象，会从spring 容器中获取。
 *          false：不会给config类生成代理对象，当直接调用方法时，会生成新的对象。
 *          也就是说，如果我们的配置类中存在某个方法的调用关系，那么这个值只能为true。如果配置类中不存在方法的调用关系，那么可以将其设置为false。
 *
 * @Import：为容器自动创建组件。
 *  @Import({User.class, DBHelper.class})：为容器自动创建出这两种类型的组件。默认组件的名字为类的全类名。
 *
 * @Conditional：条件注解。在springboot底层会大量使用这个注解，实现自动装配
 *
 * @ImportResource：可以导入配置文件。
 *  @ImportResource("classpath:spring-config.xml")：导入spring-config.xml配置文件。
 */
@Configuration
@Import({User.class, DBHelper.class})
public class MyConfig {

    /**
     * @Bean：给容器中添加一个组件，如果没有在注解中指定组件id，那么默认以方法名作为组件id。返回的值就是组件在容器中的实例
     * @return
     */
    @Bean
    public User user(){
        return new User();
    }

    /**
     * 当容器中有User组件时，才进行注入
     * @return
     */
    @ConditionalOnBean(User.class)
    public User user01(){
        return new User();
    }

    /**
     * 当容器中没有User组件时，才进行注入
     * @return
     */
    @ConditionalOnMissingBean(User.class)
    public User user02(){
        return new User();
    }
}
